Propagating a software task to different systems for execution can be difficult without the use of a programming framework. Even so, when tasks are propagated to a large number of remote systems, detecting failure of any one task can be difficult, much less attempting to undo the effects of failed tasks. Another difficulty with distributing tasks arises when a set of tasks needs to be treated as a single task for purposes of undoing any failed tasks. What is needed is a means for tracking tasks that allows for the detection and undoing of failed tasks, whether those tasks are composed of other tasks and/or are distributed.